//
//  Transceiver.h
//  Simulation
//
//  Created by Christopher Kemsley on 3/5/12.
//  Copyright (c) 2012 iAppolopolis. All rights reserved.
//

#ifndef Simulation_Transceiver_h
#define Simulation_Transceiver_h

#include "Types.hpp"
#include "TransmissionBroker.hpp"
#include "Timer.hpp"

NamespaceBegin





class	Transceiver ;
class	TransceiverDelegate ;





class	Transceiver : private ReceiverDelegate , private TransmitterDelegate
{
public:
	
	Transceiver	( TransmitterProfile const & profile , DeviceID const & inID , TransceiverDelegate & inDelegate ) ;
	
	
	
	void	setProfile	( TransmitterProfile const & profile ) ;
	
	bool	isIdle			() const ; // medium is idle
	bool	isTransmitting	() const ;
	void	transmit		( Byte const * data , Length length , DeviceID target ) ;
	
	
	
	
protected:
	
	// i.e. line isn't idle
	virtual void	receiveDidBegin () ;
	
	// i.e. line is idle
	virtual void	receiveDidFail () ;
	virtual void	receiveDidComplete	( Message * message ) ;
	
	// i.e. last byte was sent
	virtual void	transmissionDidComplete () ;
	
	
private:
	TransceiverDelegate&	mDelegate ;
	TransmitterProfile		mProfile ;
	Sim::Transmitter		mTransmitter ;
	Sim::Receiver			mReceiver ;
	
	Byte *		mBuffer ;
	Length		mLength ;
	DeviceID	mTarget ;	// transient
	
	DeviceID	mID ;
	
	OP<Invocation>	mTimeoutInvocation ;
	DP<Timer>		mTimeoutTimer ;
	
	
	typedef enum {
		kMXStateIdle				=	0 ,
		kMXStateLineIsBusy			=	1 ,
		kMXStateSendingRTS			=	2 ,	// Waiting for callback
		kMXStateWaitingForCTS		=	3 ,	// and DIFS timer is set for timeout
		kMXStateReceivingCTS		=	4 ,	// medium became busy. no timer.
		kMXStateReceivedCTS			=	5 ,	// and SIFS timer is set
		kMXStateSendingMessage		=	6 ,	// Waiting for callback
		kMXStateWaitingForAck		=	7 ,	// and DIFS timer is set for timeout
		kMXStateReceivingAck		=	8 ,	// medium became busy. no timer.
		kMXStateCompleted			=	9 ,	// and DIFS timer is set to re-assess
		kMXStateFailed				=	10,	// and DIFS timer is set to re-assess
		kMXStateHiddenTransmitter	=	11,	// and long-timer is set
	} MXState ;
	
	MXState				mState ;
	
	void	operator<<	( MXState const & state ) ; // logs it too
	
	
	void	internal_markFailed () ;
	void	internal_markComplete () ;
	
	void	internal_sendRTS () ;
	void	internal_sendBody () ;
	
	void	internal_startSIFSTimer () ;
	void	internal_startDIFSTimer () ;
	void	internal_startHiddenXMitterWait () ;
	void	internal_stopTimer () ;
	void	_timeout () ;
} ;

class	TransceiverDelegate
{
public:
	virtual void	lineDidBecomeBusy			() = 0 ;
	virtual void	lineDidBecomeOpen			() = 0 ;
	
	virtual void	connectionDidSucceed		() = 0 ;
	virtual void	connectionDidFail			() = 0 ;
} ;




NamespaceEnd

#endif
